module  iopmp_check(
    input                          iopmpck_clk_i,
    input                          iopmpck_rst_n_i,
    // from sr_reg
    input [31:0]                   iopmpck_rule_i,
    // from io_control
    input                          iopmpck_check_en_i,
    input [3:0]                    iopmpck_state_n_i,

    //from master
    input [31 : 0]                 iopmpck_haddr_i,
    input [2 : 0]                  iopmpck_hburst_i,
    input [3 : 0]                  iopmpck_hprot_i,       //hprot[0]为0，代表是来自tee的访问信号，为1，代表是来自ree的访问信号
    input                          iopmpck_hsel_i,
    input [2 : 0]                  iopmpck_hsize_i,
    input [1 : 0]                  iopmpck_htrans_i,
    input [31 : 0]                 iopmpck_hwdata_i,
    input                          iopmpck_hwrite_i,
    //from slave
    input [31 : 0]                 iopmpck_hrdata_i,
    input                          iopmpck_hready_i,
    input [1 : 0]                  iopmpck_hresp_i,
    input                          iopmpck_intr_i,

   //to slave
//    output reg [31 : 0]                iopmpck_haddr_o,
//    output reg [2 : 0]                 iopmpck_hburst_o,
//    output reg [3 : 0]                 iopmpck_hprot_o, 
//    output reg                         iopmpck_hsel_o,
//    output reg [2 : 0]                 iopmpck_hsize_o,
//    output reg [1 : 0]                 iopmpck_htrans_o,
//    output reg [31 : 0]                iopmpck_hwdata_o,
//    output reg                         iopmpck_hwrite_o,
//    //to master
//    output reg [31 : 0]                iopmpck_hrdata_o,
//    output reg                         iopmpck_hready_o,
//    output reg [1 : 0]                 iopmpck_hresp_o,
//    output reg                         iopmpck_intr_o,
//    //to sr_reg
//    output reg                         iopmpck_error_o,
//    output reg [15:0]                  iopmpck_iohit_o,
//    //to sr_control
//    output reg                         iopmpck_hwren_o,
//    output reg                         iopmpck_hrden_o,
//    output reg                         iopmpck_hrdy_o
    
    output  [31 : 0]                iopmpck_haddr_o,
    output  [2 : 0]                 iopmpck_hburst_o,
    output  [3 : 0]                 iopmpck_hprot_o, 
    output                          iopmpck_hsel_o,
    output  [2 : 0]                 iopmpck_hsize_o,
    output  [1 : 0]                 iopmpck_htrans_o,
    output  [31 : 0]                iopmpck_hwdata_o,
    output                          iopmpck_hwrite_o,
    //to master
    output  [31 : 0]                iopmpck_hrdata_o,
    output                          iopmpck_hready_o,
    output  [1 : 0]                 iopmpck_hresp_o,
    output                          iopmpck_intr_o,
    //to sr_reg
    output                          iopmpck_error_o,
    output  [15:0]                  iopmpck_iohit_o,
    //to sr_control
    output                          iopmpck_hwren_o,
    output                          iopmpck_hrden_o,
    output                          iopmpck_hrdy_o
);




reg [31:0]    check_rule; // 修改的check规则
reg [4:0]     state;
reg [4:0]     state_next;
wire          write_en;
wire          read_en;
wire [1:0]    pri_wr;
wire          bus_ieqo;
wire [15:0]   io_hit;
reg           bus_read_check_b;
wire          bus_read_access;

//old assign bus_ieqo  = ((~iopmpck_hwrite_i & pri_wr[0]) | (iopmpck_hwrite_i & pri_wr[1]) | (iopmpck_hprot_i[0]==1'b0)) & (iopmpck_check_en_i==1'b1);

assign write_en  = (iopmpck_htrans_i[1] == 1) & (iopmpck_hwrite_i == 1) & (iopmpck_hsel_i == 1);
assign read_en   = (iopmpck_htrans_i[1] == 1) & (iopmpck_hwrite_i == 0) & (iopmpck_hsel_i == 1);
//new
assign bus_ieqo  = ((read_en & pri_wr[0]) | (write_en & pri_wr[1]) | (iopmpck_hprot_i[0]==1'b0)) & (iopmpck_check_en_i==1'b1);

assign w_r_ready = iopmpck_hready_i;

//更新检查规则
always @(posedge iopmpck_clk_i or negedge iopmpck_rst_n_i) begin
    if(!iopmpck_rst_n_i)
        check_rule <= 32'hFFFF_FFFC;
    else if(iopmpck_check_en_i == 1'b0)
        check_rule <= iopmpck_rule_i;
    else
        check_rule <= check_rule;
end
//limit read after read_en 
always @(posedge iopmpck_clk_i or negedge iopmpck_rst_n_i) begin
    if(!iopmpck_rst_n_i)
        bus_read_check_b <= 1'h0;
    else if(bus_ieqo == 1'b0 && read_en == 1'b1)
        bus_read_check_b <= 1'h1;
    else if(iopmpck_state_n_i[3] == 1'b1)
        bus_read_check_b <= 1'h0;
    else
        bus_read_check_b <= bus_read_check_b;
end



assign bus_read_access = ~(bus_read_check_b & iopmpck_state_n_i[3]);

//always @(posedge iopmpck_clk_i ) begin
//    iopmpck_haddr_o  <= iopmpck_haddr_i  ;
//    iopmpck_hwrite_o <= iopmpck_hwrite_i ;
//    iopmpck_hprot_o  <= iopmpck_hprot_i  ;
//    iopmpck_hsize_o  <= iopmpck_hsize_i  ;
//    iopmpck_htrans_o <= iopmpck_htrans_i ;
//    iopmpck_hwdata_o <= iopmpck_hwdata_i ;
//    iopmpck_hburst_o <= iopmpck_hburst_i ;
//    iopmpck_hsel_o   <= (bus_ieqo == 1'b1) ? iopmpck_hsel_i : 1'b0;
//    iopmpck_hrdata_o <= iopmpck_hrdata_i;
//    iopmpck_hresp_o  <= iopmpck_hresp_i;
//    iopmpck_intr_o   <= (bus_ieqo == 1'b1) ? iopmpck_intr_i : 1'b0;
//    iopmpck_hready_o <=  iopmpck_hready_i ;
//    iopmpck_error_o  <= (bus_ieqo == 1'b1) ? 1'b0 : 1'b1;
//    iopmpck_iohit_o  <= (bus_ieqo == 1'b1) ? 16'd0 : io_hit;
//    iopmpck_hwren_o  <= write_en;
//    iopmpck_hrden_o  <= read_en;
//    iopmpck_hrdy_o   <= iopmpck_hready_i;  
//end

assign   iopmpck_haddr_o  = iopmpck_haddr_i  ;
assign   iopmpck_hwrite_o = iopmpck_hwrite_i ;
assign   iopmpck_hprot_o  = iopmpck_hprot_i  ;
assign   iopmpck_hsize_o  = iopmpck_hsize_i  ;
assign   iopmpck_htrans_o = iopmpck_htrans_i ;
assign   iopmpck_hwdata_o = iopmpck_hwdata_i ;
assign   iopmpck_hburst_o = iopmpck_hburst_i ;
assign   iopmpck_hsel_o   = (bus_ieqo == 1'b1) ? iopmpck_hsel_i : 1'b0;
assign   iopmpck_hrdata_o = (bus_read_access==1'b1) ? iopmpck_hrdata_i : 32'd0;
assign   iopmpck_hresp_o  = iopmpck_hresp_i;
assign   iopmpck_intr_o   = iopmpck_intr_i ;
assign   iopmpck_hready_o =  iopmpck_hready_i ;
assign   iopmpck_error_o  = (bus_ieqo == 1'b1) ? 1'b0 : 1'b1;
assign   iopmpck_iohit_o  = (bus_ieqo == 1'b1) ? 16'd0 : io_hit;
assign   iopmpck_hwren_o  = write_en;
assign   iopmpck_hrden_o  = read_en;
assign   iopmpck_hrdy_o   = iopmpck_hready_i;  

iopmp_apb0addr_match sr_apb0addr_match_inst 
(
    .addrmt_haddr_i (iopmpck_haddr_i),
    .addrmt_prireg_i(check_rule),
    .addrmt_pri_o   (pri_wr),
    .addrmt_hit_o   (io_hit)
);

endmodule
